﻿// Decompiled with JetBrains decompiler
// Type: Netick.ExecutionListLL
// Assembly: Netick, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 6726ECA1-C773-4CF7-8952-E81B30D93B52
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.xml

using System;
using System.Collections.Generic;

#nullable disable
namespace Netick;

public sealed class ExecutionListLL
{
  private NetickEngine Engine;
  internal List<BehaviourList> BehaviourChains = new List<BehaviourList>(64 /*0x40*/);
  internal Dictionary<Type, BehaviourList> TypeToBehaviourChain = new Dictionary<Type, BehaviourList>(64 /*0x40*/);

  internal ExecutionListLL(NetickEngine engine)
  {
    this.Engine = engine;
    for (int index = 0; index < this.Engine._reflectionData.NetickBehaviourTypes.Count; ++index)
    {
      Type netickBehaviourType = this.Engine._reflectionData.NetickBehaviourTypes[index];
      BehaviourList behaviourList = new BehaviourList(this.Engine.GetBehaviourOrder(netickBehaviourType), 100);
      this.TypeToBehaviourChain.Add(netickBehaviourType, behaviourList);
      this.BehaviourChains.Add(behaviourList);
      this.BehaviourChains.Sort((Comparison<BehaviourList>) ((x, y) => x.Order.CompareTo(y.Order)));
    }
  }

  public void Clear()
  {
    foreach (BehaviourList behaviourChain in this.BehaviourChains)
      Array.Clear((Array) behaviourChain.List, 0, behaviourChain.List.Length);
  }

  internal void AddToSimulation(Entity entity)
  {
    INetickEntity userEntity = entity.UserEntity;
    if (entity.IsInSimulation)
      return;
    if (this.Engine.IsClient && !entity._isOnPredictedList && (userEntity.PredictionMode == Relevancy.Everyone || this.Engine.LocalPlayer.IsThisInputSourceOfEntity(entity)))
    {
      this.Engine._cliSim.PredictedEntities.Add(entity);
      entity._isOnPredictedList = true;
    }
    entity.IsInSimulation = true;
    foreach (INetickScript allScript in userEntity.AllScripts)
      this.AddBehaviour(allScript);
  }

  internal void RemoveFromSimulation(Entity entity)
  {
    INetickEntity userEntity = entity.UserEntity;
    if (!entity.IsInSimulation)
      return;
    if ((userEntity.PredictionMode == Relevancy.Everyone || this.Engine.LocalPlayer.IsThisInputSourceOfEntity(entity)) && this.Engine.IsClient && entity._isOnPredictedList)
    {
      this.Engine._cliSim.PredictedEntities.Remove(entity);
      entity._isOnPredictedList = false;
    }
    entity.IsInSimulation = false;
    foreach (INetickScript allScript in userEntity.AllScripts)
      this.RemoveBehaviour(allScript);
  }

  public void RemoveAndInvokeNetworkDestroy(Entity obj)
  {
    obj.IsInSimulation = false;
    INetickScript[] allScripts = obj.UserEntity.AllScripts;
    if (this.Engine.IsServer || obj.IsReady)
    {
      for (int index = 0; index < allScripts.Length; ++index)
      {
        try
        {
          allScripts[index].NetworkDestroy();
        }
        catch (Exception ex)
        {
          INetickScript targetScript = allScripts[index];
          NetickLogger.LogError((object) ex, (object) targetScript);
        }
      }
    }
    for (int index = 0; index < allScripts.Length; ++index)
      this.RemoveBehaviour(allScripts[index]);
  }

  internal void RemoveBehaviour(INetickScript behaviour)
  {
    this.TypeToBehaviourChain[behaviour.GetType()].Remove(behaviour);
  }

  internal void AddBehaviour(INetickScript newBehaviour)
  {
    newBehaviour.Initialize(this.Engine);
    this.TypeToBehaviourChain[newBehaviour.GetType()].Add(newBehaviour);
  }

  internal void ExecuteNetworkFixedUpdate()
  {
    for (int index1 = 0; index1 < this.BehaviourChains.Count; ++index1)
    {
      BehaviourList behaviourChain = this.BehaviourChains[index1];
      INetickScript[] list = this.BehaviourChains[index1].List;
      int count = behaviourChain.Count;
      for (int index2 = 0; index2 < count; ++index2)
      {
        try
        {
          list[index2].NetworkFixedUpdate();
        }
        catch (Exception ex)
        {
          BehaviourList targetScript = behaviourChain;
          NetickLogger.LogError((object) ex, (object) targetScript);
        }
      }
    }
  }

  internal void ExecuteNetworkUpdate()
  {
    for (int index1 = 0; index1 < this.BehaviourChains.Count; ++index1)
    {
      BehaviourList behaviourChain = this.BehaviourChains[index1];
      INetickScript[] list = this.BehaviourChains[index1].List;
      int count = behaviourChain.Count;
      for (int index2 = 0; index2 < count; ++index2)
      {
        try
        {
          list[index2].NetworkUpdate();
        }
        catch (Exception ex)
        {
          BehaviourList targetScript = behaviourChain;
          NetickLogger.LogError((object) ex, (object) targetScript);
        }
      }
    }
  }

  internal void ExecuteNetworkRender()
  {
    for (int index1 = 0; index1 < this.BehaviourChains.Count; ++index1)
    {
      BehaviourList behaviourChain = this.BehaviourChains[index1];
      INetickScript[] list = this.BehaviourChains[index1].List;
      int count = behaviourChain.Count;
      for (int index2 = 0; index2 < count; ++index2)
      {
        try
        {
          list[index2].NetworkRender();
        }
        catch (Exception ex)
        {
          BehaviourList targetScript = behaviourChain;
          NetickLogger.LogError((object) ex, (object) targetScript);
        }
      }
    }
  }

  internal void ExecuteGameEngineIntoNetcode()
  {
    for (int index1 = 0; index1 < this.BehaviourChains.Count; ++index1)
    {
      BehaviourList behaviourChain = this.BehaviourChains[index1];
      INetickScript[] list = this.BehaviourChains[index1].List;
      int count = behaviourChain.Count;
      for (int index2 = 0; index2 < count; ++index2)
      {
        try
        {
          list[index2].GameEngineIntoNetcode();
        }
        catch (Exception ex)
        {
          BehaviourList targetScript = behaviourChain;
          NetickLogger.LogError((object) ex, (object) targetScript);
        }
      }
    }
  }
}
